<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Compare PDFs</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.4.120/pdf.min.js"></script>
    <style>
    html { font-family: verdana; }
        #dropZone {
            border: 2px dashed #ccc;
            border-radius: 20px;
            width: 480px;
            padding: 20px;
            text-align: center;
            margin: 20px auto;
        }
        #dropZone.dragover {
            background-color: #e1f5fe;
            border-color: #03a9f4;
        }
        .page-container {
            display: flex;
            margin-bottom: 20px;
        }
        .page-container > div {
            margin-right: 10px;
        }
        #error {
            color: red;
            text-align: center;
        }
    </style>
</head>
<body>
    <h1>Compare PDFs</h1>
    <div id="dropZone">
        <p>Drag and drop two PDF files here, or click to select files</p>
        <input type="file" id="fileInput" multiple accept=".pdf" style="display: none;">
    </div>
    <div id="error"></div>
    <div id="pdfComparison"></div>

    <script>
        // Initialize PDF.js worker
        pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.4.120/pdf.worker.min.js';

        const dropZone = document.getElementById('dropZone');
        const fileInput = document.getElementById('fileInput');
        const errorDiv = document.getElementById('error');
        const pdfComparison = document.getElementById('pdfComparison');

        let pdf1, pdf2;

        dropZone.addEventListener('click', () => fileInput.click());

        dropZone.addEventListener('dragover', (e) => {
            e.preventDefault();
            dropZone.classList.add('dragover');
        });

        dropZone.addEventListener('dragleave', () => {
            dropZone.classList.remove('dragover');
        });

        dropZone.addEventListener('drop', handleFiles);
        fileInput.addEventListener('change', handleFiles);

        function handleFiles(e) {
            e.preventDefault();
            dropZone.classList.remove('dragover');
            const files = e.dataTransfer ? e.dataTransfer.files : e.target.files;

            if (files.length === 2) {
                pdf1 = files[0];
                pdf2 = files[1];
                errorDiv.textContent = '';
                renderPDFs();
            } else {
                errorDiv.textContent = 'Please select exactly two PDF files.';
            }
        }

        async function renderPDFs() {
            try {
                const [doc1, doc2] = await Promise.all([
                    pdfjsLib.getDocument(URL.createObjectURL(pdf1)).promise,
                    pdfjsLib.getDocument(URL.createObjectURL(pdf2)).promise
                ]);

                const pageCount = Math.max(doc1.numPages, doc2.numPages);
                pdfComparison.innerHTML = '';

                for (let i = 1; i <= pageCount; i++) {
                    const [page1, page2] = await Promise.all([
                        i <= doc1.numPages ? doc1.getPage(i) : null,
                        i <= doc2.numPages ? doc2.getPage(i) : null
                    ]);

                    const [canvas1, canvas2] = await Promise.all([
                        page1 ? renderPageToCanvas(page1) : createEmptyCanvas(),
                        page2 ? renderPageToCanvas(page2) : createEmptyCanvas()
                    ]);

                    const diffCanvas = compareCanvases(canvas1, canvas2);

                    displayPage(i, canvas1, canvas2, diffCanvas);
                }
            } catch (error) {
                console.error('Error rendering PDFs:', error);
                errorDiv.textContent = 'Error rendering PDFs. Please try again with valid PDF files.';
            }
        }

        async function renderPageToCanvas(page) {
            const scale = 1.5;
            const viewport = page.getViewport({ scale });
            const canvas = document.createElement('canvas');
            const context = canvas.getContext('2d');
            canvas.height = viewport.height;
            canvas.width = viewport.width;

            await page.render({ canvasContext: context, viewport }).promise;
            return canvas;
        }

        function createEmptyCanvas() {
            const canvas = document.createElement('canvas');
            canvas.width = 1;
            canvas.height = 1;
            return canvas;
        }

        function compareCanvases(canvas1, canvas2) {
            const width = Math.max(canvas1.width, canvas2.width);
            const height = Math.max(canvas1.height, canvas2.height);

            const diffCanvas = document.createElement('canvas');
            diffCanvas.width = width;
            diffCanvas.height = height;
            const ctx = diffCanvas.getContext('2d');

            const img1 = canvas1.getContext('2d').getImageData(0, 0, canvas1.width, canvas1.height);
            const img2 = canvas2.getContext('2d').getImageData(0, 0, canvas2.width, canvas2.height);

            const diff = ctx.createImageData(width, height);

            for (let y = 0; y < height; y++) {
                for (let x = 0; x < width; x++) {
                    const i = (y * width + x) * 4;
                    const r1 = img1.data[i] || 255;
                    const g1 = img1.data[i + 1] || 255;
                    const b1 = img1.data[i + 2] || 255;
                    const r2 = img2.data[i] || 255;
                    const g2 = img2.data[i + 1] || 255;
                    const b2 = img2.data[i + 2] || 255;

                    if (r1 !== r2 || g1 !== g2 || b1 !== b2) {
                        diff.data[i] = 255;
                        diff.data[i + 1] = 0;
                        diff.data[i + 2] = 0;
                        diff.data[i + 3] = 128;
                    }
                }
            }

            ctx.putImageData(diff, 0, 0);
            return diffCanvas;
        }

        function displayPage(pageNumber, canvas1, canvas2, diffCanvas) {
            const container = document.createElement('div');
            container.className = 'page-container';

            const addCanvas = (canvas, title) => {
                const div = document.createElement('div');
                const h3 = document.createElement('h3');
                h3.textContent = title;
                div.appendChild(h3);
                div.appendChild(canvas);
                container.appendChild(div);
            };

            addCanvas(canvas1, `PDF 1 - Page ${pageNumber}`);
            addCanvas(canvas2, `PDF 2 - Page ${pageNumber}`);
            addCanvas(diffCanvas, `Differences - Page ${pageNumber}`);

            pdfComparison.appendChild(container);
        }
    </script>

<h3>Claude 3.5 Sonnet prompts used:</h3>

<ol>
  <li><code>Build a tool where I can drag and drop on two PDF files and it uses PDF.js to turn each of their pages into canvas elements and then displays those pages side by side with a third image that highlights any differences between them, if any differences exist</code></li>
  <li><code>rewrite that code to not use React at all</code></li>
  </ol>

    </body>
</html>